package domain;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;


import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.context.ApplicationContext;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.web.context.support.WebApplicationContextUtils;

import util.HibernateUtil;

public class DAOContact extends HibernateDaoSupport implements IDAOContact{

	/**
	 * Rajoute un contact dans la base de donnees.
	 * @param firstname
	 * @param lastname
	 * @param email
	 * @return renvoit le nouveau contact
	 */
	public Contact addContact( String firstname, String lastname, String email){

		Contact contact = new Contact();
		contact.setFirstName(firstname);
		contact.setLastName(lastname);
		contact.setEmail(email);

		/*Session session = null;
		SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
		session = sessionFactory.openSession();
		Transaction tx = session.beginTransaction();
		session.save(contact);
		tx.commit();*/

		getHibernateTemplate().save(contact);
		return contact;
	}

	public Contact addContact(Contact contact){
		getHibernateTemplate().save(contact);
		return contact;
	}

	public Contact addContact(final String firstname, final String lastname, final String email,
			final String zip, final String city,final String country, final String street,
			final String phoneNumber, final String phoneKind, final ArrayList<Long> groupIds, final String numSiret){
		return (Contact)getHibernateTemplate().execute(new HibernateCallback(){
			public Object doInHibernate(Session session) throws
			HibernateException{

				Contact contact;
				if(numSiret == null){
					contact = new Contact(firstname, lastname, email);
				}
				else
				{
					contact = new Entreprise(firstname, lastname, email, Integer.parseInt(numSiret));
				}

				Address adress = new Address(street, city, zip, country);

				PhoneNumber phone = new PhoneNumber(phoneKind, phoneNumber);

				/*Session session = HibernateUtil.getSessionFactory().openSession();
			Transaction tx = session.beginTransaction();*/


				contact.setAdd(adress);
				//contactGroup = (ContactGroup) session.get(ContactGroup.class, contactGroup.getGroupId());
				for(long groupId : groupIds){
					ContactGroup contactGroup = (ContactGroup) session.get(ContactGroup.class, groupId);
					if (contactGroup != null){
						contact.addGroup(contactGroup);
						session.saveOrUpdate(contactGroup);
					}
				}
				contact.addPhone(phone);

				session.save(contact);
				/*tx.commit();
				session.close();*/


				return contact;
			}

		});
	}

	/**
	 * Suppresion d'un contact a partir de son identifiant
	 * @param id
	 * @return vrai si la suppression a bien ete effectuee
	 */
	public boolean deleteContact(final long id){
		return (Boolean)getHibernateTemplate().execute(new HibernateCallback(){
			public Object doInHibernate(Session session) throws
			HibernateException{
				boolean success=false;
				/*Session session = HibernateUtil.getSessionFactory().openSession();
				Transaction tx = session.beginTransaction();*/
				Contact contact = (Contact) session.get(Contact.class, id);
				for (ContactGroup group : contact.getGroups()){
					group.getContacts().size();
					group.removeContact(contact);
				}

				session.delete(contact);
				/*tx.commit();
				session.close();*/
				success = true;

				return success;
			}
		});
	}

	/**
	 * Recuperation d'un contact a partir de son identifiant
	 * @param id
	 * @return
	 */
	public Contact getContact(final long id){
		return (Contact)getHibernateTemplate().execute(new HibernateCallback(){
			public Object doInHibernate(Session session) throws
			HibernateException{
				Contact contact;
				//Session session = HibernateUtil.getSessionFactory().openSession();			
				contact = (Contact) session.get(Contact.class, id);
				//session.close();
				return contact;
			}
		});
	}
	
	public ArrayList<Contact> getAllContacts() {
		
		final ArrayList<Contact> contacts = new ArrayList<Contact>();
		getHibernateTemplate().execute(new HibernateCallback(){
			public Object doInHibernate(Session sessionHibernate) throws
			HibernateException{
				
				Query requete = sessionHibernate.createQuery("select contact from Contact contact").setCacheable(true);
				List<?> list =  requete.list();
				for ( Object obj : list){
					contacts.add((Contact)obj);
				}
				return contacts;
			}
		});	
		
		return contacts;
	}

	public boolean modifyContact(long id, String firstname, String lastname, String email) {
		Contact contact;
		boolean success = false;
		/*Session session = HibernateUtil.getSessionFactory().openSession();
		Transaction tx = session.beginTransaction();
		contact = (Contact) session.get(Contact.class, id);*/
		contact = (Contact) getHibernateTemplate().get(Contact.class, id);
		contact.setFirstName(firstname);
		contact.setLastName(lastname);
		contact.setEmail(email);
		/*tx.commit();
		session.close();*/
		return success;
	}

	/**
	 * Methode qui modifie les coordonees d'un contact
	 * @param id
	 * @param firstname
	 * @param lastname
	 * @param email
	 * @return
	 */
	public boolean modifyContact(final long id,final String firstname, final String lastname, final String email,
			final String zip, final String city,final String country, final String street,
			final String phoneNumber, final String phoneKind, final ArrayList<Long> groupIds, final String numSiret){
		return (Boolean)getHibernateTemplate().execute(new HibernateCallback(){
			public Object doInHibernate(Session sessionHibernate) throws
			HibernateException{
				Contact contact;
				if(numSiret == null){
					contact = (Contact) sessionHibernate.get(Contact.class, id);
				}
				else
				{
					contact =  (Entreprise) sessionHibernate.get(Entreprise.class, id);
					((Entreprise)contact).setNumSiret(Integer.valueOf(numSiret));

				}
				contact.setFirstName(firstname);
				contact.setLastName(lastname);
				contact.setEmail(email);

				Address adress = new Address(street, city, zip, country);

				PhoneNumber phone = new PhoneNumber(phoneKind, phoneNumber);

				/*Session session = HibernateUtil.getSessionFactory().openSession();
		Transaction tx = session.beginTransaction();*/


				contact.setAdd(adress);
				
				for(long groupId : groupIds){
					ContactGroup contactGroup = (ContactGroup) sessionHibernate.get(ContactGroup.class, groupId);
					if (contactGroup != null){
						contact.addGroup(contactGroup);
						sessionHibernate.saveOrUpdate(contactGroup);
					}
				}

				contact.addPhone(phone);

				//session.saveOrUpdate(contactGroup);
				sessionHibernate.saveOrUpdate(contact);
				//getHibernateTemplate().persist(contactGroup);

				/*session.save(contact);
				tx.commit();
				session.close();*/


				return true;
			}
		});
	}

	/**
	 * Renvoit la liste des contacts correspondant au prenom firrstname
	 * @param firstname
	 * @return
	 */
	public ArrayList<Contact> getContactByFirstName(final String firstname){

		final ArrayList<Contact> contacts = new ArrayList<Contact>();
		getHibernateTemplate().execute(new HibernateCallback(){
			public Object doInHibernate(Session sessionHibernate) throws
			HibernateException{
				/*Session session = HibernateUtil.getSessionFactory().openSession();
				Query requete = session.createQuery("select contact from Contact contact where contact.firstName = '" + firstname + "'");
				List<?> list =  requete.list();*/
				Query requete = sessionHibernate.createQuery("select contact from Contact contact where contact.firstName = '" + firstname + "'").setCacheable(true);
				List<?> list =  requete.list();
				for ( Object obj : list){
					contacts.add((Contact)obj);
				}
				return contacts;
			}
		});
		//session.close();
		return contacts;
	}


	/**
	 * Renvoit la liste des contacts correspondant au nom lastname
	 * @param lastname
	 * @return
	 */
	public ArrayList<Contact> getContactByLastName(final String lastname){

		final ArrayList<Contact> contacts = new ArrayList<Contact>();
		/*Session session = HibernateUtil.getSessionFactory().openSession();
		List<?> list = session.createCriteria(Contact.class)
				.add(Restrictions.like("lastName", lastname) ).list();*/
		getHibernateTemplate().execute(new HibernateCallback(){
			public Object doInHibernate(Session sessionHibernate) throws
			HibernateException{
				Query requete = sessionHibernate.createQuery("select contact from Contact contact where contact.lastName = '" + lastname + "'");
				List<?> list =  requete.list();
				for ( Object obj : list){
					contacts.add((Contact)obj);
				}
				return contacts;
			}
		});
		//session.close();
		return contacts;
	}

	/**
	 * Renvoit la liste des contacts correspondant a l'email email
	 * @param email
	 * @return
	 */
	public ArrayList<Contact> getContactByEmail(final String email){
		final ArrayList<Contact> contacts = new ArrayList<Contact>();
		/*Session session = HibernateUtil.getSessionFactory().openSession();
		List<?> list = session.createCriteria(Contact.class)
				.add(Restrictions.like("lastName", lastname) ).list();*/
		getHibernateTemplate().execute(new HibernateCallback(){
			public Object doInHibernate(Session sessionHibernate) throws
			HibernateException{
				Query requete = sessionHibernate.createQuery("select contact from Contact contact where contact.email = '" + email + "'");
				List<?> list =  requete.list();
				for ( Object obj : list){
					contacts.add((Contact)obj);
				}
				return contacts;
			}
		});
		//session.close();
		return contacts;
	}

}
